package cn.jn.lhm.teacher.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.jn.lhm.service.config.exception.GlobalException;
import cn.jn.lhm.service.config.exception.handler.GlobalExceptionHandler;
import cn.jn.lhm.teacher.entity.*;
import cn.jn.lhm.teacher.entity.frontvo.CourseDataVo;
import cn.jn.lhm.teacher.entity.frontvo.CourseInfoFrontVo;
import cn.jn.lhm.teacher.entity.vo.CourseInfoVo;
import cn.jn.lhm.teacher.entity.vo.CoursePublishVo;
import cn.jn.lhm.teacher.entity.vo.CourseQueryCondition;
import cn.jn.lhm.teacher.feign.VodClient;
import cn.jn.lhm.teacher.mapper.*;
import cn.jn.lhm.teacher.service.EduCourseService;
import cn.jn.lhm.utils.R;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author LHM
 * @Tips 热爱每一天，奋斗每一天
 * @date 2020/6/2 - 21:33
 */
@Service
@Slf4j
public class EduCourseServiceImpl implements EduCourseService {

    @Resource
    private EduCourseMapper eduCourseMapper;

    @Resource
    private EduCourseDescMapper eduCourseDescMapper;

    @Resource
    private EduCommentMapper eduCommentMapper;

    @Resource
    private EduChapterMapper eduChapterMapper;

    @Resource
    private EduVideoMapper eduVideoMapper;

    @Resource
    private VodClient vodClient;


    @Override
    public void saveCommentInfo(EduComment eduComment) {
        eduCommentMapper.insert(eduComment);
    }

    @Override
    public String saveCourseInfo(CourseInfoVo courseInfo) {
        //转换courseInfo 为 EduCourse
        //向课程信息表中添加数据
        EduCourse eduCourse = new EduCourse();
        BeanUtils.copyProperties(courseInfo, eduCourse);
        int result = eduCourseMapper.insert(eduCourse);
        if (result == 0) {
            throw new GlobalException(20001, "添加课程信息失败");
        }
        //向课程描述表中添加数据
        EduCourseDescription description = new EduCourseDescription();
        description.setDescription(courseInfo.getDescription());
        //设置描述的Id和课程的Id一致，不让其自动生成自己的Id
        description.setId(eduCourse.getId());
        eduCourseDescMapper.insert(description);
        //为了后面的添加，需要返回课程Id
        return eduCourse.getId();
    }

    @Override
    public CourseInfoVo getCourseInfo(String id) {
        EduCourse course = eduCourseMapper.selectById(id);
        EduCourseDescription courseDescription = eduCourseDescMapper.selectById(id);
        CourseInfoVo courseInfoVo = new CourseInfoVo();
        BeanUtils.copyProperties(course, courseInfoVo);
        courseInfoVo.setDescription(courseDescription.getDescription());
        return courseInfoVo;
    }

    @Override
    public void updateCourseInfo(CourseInfoVo courseInfoVo) {
        EduCourse eduCourse = new EduCourse();
        BeanUtils.copyProperties(courseInfoVo, eduCourse);
        int updateCourse = eduCourseMapper.updateById(eduCourse);
        if (updateCourse == 0) {
            throw new GlobalException(20001, "修改课程信息失败");
        }
        EduCourseDescription eduCourseDescription = new EduCourseDescription();
        eduCourseDescription.setId(courseInfoVo.getId());
        eduCourseDescription.setDescription(courseInfoVo.getDescription());
        eduCourseDescMapper.updateById(eduCourseDescription);
    }

    @Override
    public CoursePublishVo getPublishCourseInfoByCourseId(String id) {
        return eduCourseMapper.getPublishCourseInfo(id);
    }

    @Override
    public void changeCoursePublish(EduCourse eduCourse) {
        eduCourseMapper.updateById(eduCourse);
    }

    @Override
    public List<EduCourse> getAllCourse() {
        QueryWrapper<EduCourse> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("gmt_modified");
        return eduCourseMapper.selectList(wrapper);
    }

    @Override
    public R getCourseByCondition(CourseQueryCondition queryCondition, Page<EduCourse> page) {
        IPage<EduCourse> eduCourseIPage;
        QueryWrapper<EduCourse> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("gmt_modified");
        if (null != queryCondition) {
            if (null != queryCondition.getStatus()) {
                wrapper.eq("status", queryCondition.getStatus());
            }
            if (null != queryCondition.getEnd()) {
                wrapper.le("view_count", queryCondition.getEnd());
            }
            if (null != queryCondition.getStart()) {
                wrapper.ge("view_count", queryCondition.getStart());
            }
            if (null != queryCondition.getTitle()) {
                wrapper.like("title", queryCondition.getTitle());
            }
        }
        eduCourseIPage = eduCourseMapper.selectPage(page, wrapper);
        return R.ok().data("data", eduCourseIPage.getRecords()).data("total", eduCourseIPage.getTotal());
    }

    @Override
    public void removeCourseAllInfo(String id) {
        deleteVideoAllInfoByCourseId(id);
        //删除章节
        QueryWrapper<EduChapter> chapterQueryWrapper = new QueryWrapper<>();
        chapterQueryWrapper.eq("course_id", id);
        eduChapterMapper.delete(chapterQueryWrapper);
        //删除课程描述信息
        eduCourseDescMapper.deleteById(id);
        int result = eduCourseMapper.deleteById(id);
        if (result != 1) {
            throw new GlobalException(20001, "删除失败");
        }
    }

    @Override
    public List<EduCourse> listByWrap(QueryWrapper<EduCourse> courseQueryWrapper) {
        return eduCourseMapper.selectList(courseQueryWrapper);
    }

    @Override
    public List<EduCourse> getCourseInfoByTeacherId(String id) {
        QueryWrapper<EduCourse> wrapper = new QueryWrapper<>();
        wrapper.eq("teacher_id", id);
        return eduCourseMapper.selectList(wrapper);
    }

    @Override
    public Map<String, Object> getCourseListByFrontCondition(Page<EduCourse> page, CourseInfoFrontVo frontVo) {
        Map<String, Object> map = new HashMap<>();
        QueryWrapper<EduCourse> wrapper = new QueryWrapper<>();
        if (frontVo != null) {
            if (!StrUtil.hasEmpty(frontVo.getTeacherId())){
                wrapper.eq("teacher_id", frontVo.getTeacherId());
            }
            if (!StrUtil.hasEmpty(frontVo.getSubjectParentId())) {
                wrapper.eq("subject_parent_id", frontVo.getSubjectParentId());
            }
            if (!StrUtil.hasEmpty(frontVo.getSubjectId())) {
                //TODO 查询一级分类时应该把属于该一级分类的二级分类全部查询出来
                wrapper.eq("subject_id", frontVo.getSubjectId());
            }
            if (!StrUtil.hasEmpty(frontVo.getCountSort())) {
                wrapper.orderByDesc("buy_count");
            }
            if (!StrUtil.hasEmpty(frontVo.getGmtCreateSort())) {
                wrapper.orderByDesc("gmt_create");
            }
            if (!StrUtil.hasEmpty(frontVo.getPriceSort())) {
                wrapper.orderByDesc("price");
            }
        }
        eduCourseMapper.selectPage(page, wrapper);
        map.put("courseList", page.getRecords());
        map.put("size", page.getSize());
        map.put("pages", page.getPages());
        map.put("hasNext", page.hasNext());
        map.put("current", page.getCurrent());
        map.put("total", page.getTotal());
        map.put("hasPrevious", page.hasPrevious());
        return map;
    }

    @Override
    public CourseDataVo getCourseAllInfo(String id) {
        return eduCourseMapper.selectCourseAllInfo(id);
    }

    @Override
    public IPage<EduComment> getCommentInfoByCourseId(String id, Page<EduComment> page) {
        QueryWrapper<EduComment> wrapper = new QueryWrapper<>();
        wrapper.eq("course_id", id);
        wrapper.orderByDesc("gmt_create");
        return eduCommentMapper.selectPage(page, wrapper);
    }

    /**
     * 根据课程Id删除小节信息以及所有的视频信息
     *
     * @param id
     */
    private void deleteVideoAllInfoByCourseId(String id) {
        //删除小节
        //根据视频视频Id删除所有的视频信息
        QueryWrapper<EduVideo> videoQueryWrapper = new QueryWrapper<>();
        videoQueryWrapper.eq("course_id", id);
        //这里也可以直接查询某一项，但是为了统一使用，还是查询所有
        List<EduVideo> videoList = eduVideoMapper.selectList(videoQueryWrapper);
        if (CollUtil.isNotEmpty(videoList)) {
            List<String> batchDeleteList = videoList.stream().map(EduVideo::getVideoSourceId).collect(Collectors.toList());
            //批量删除所有的视频
            R r = vodClient.deleteBatch(batchDeleteList);
            //判断是否触发熔断
            if (r.getCode() == 50000) {
                throw new GlobalException(20001, "系统故障，情稍候再试");
            }
        }
        //删除小节
        eduVideoMapper.delete(videoQueryWrapper);
    }
}
